

package com.beans;


import com.entidades.Cupones;
import com.entidades.Datoscuponesventa;
import com.entidades.Formaspago;
import com.entidades.Negocios;
import com.entidades.Ofertas;
import com.entidades.Usuarios;
import com.entidades.Ventas;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.el.ELException;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import javax.imageio.ImageIO;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.servlet.ServletContext;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
import jbarcodebean.JBarcodeBean;
import net.sourceforge.jbarcodebean.BarcodeException;
import net.sourceforge.jbarcodebean.model.Interleaved25;
import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.primefaces.model.DefaultStreamedContent;


    
/**
 * <p>A simple managed bean to mediate between the user
 * and the persistence layer.</p>
 * @author rlubke
 */
@Named("cVen")
public class controlVentas {
    /**
     * <p>The <code>PersistenceContext</code>.</p>
     */
    @PersistenceContext 
    private EntityManager em;
    
    /**
     * <p>The transaction resource.</p>
     */
    @Resource 
    private UserTransaction utx2;

    
    public controlVentas() {  
    }  

    //variables ventas
    private Ofertas oC; //oferta elegida para comprar
    private Negocios nC; //negocio de oferta elegida para comprar

    private Integer cvenCantidad;
    private String cvenNombre;
    private String cvenEmail;
    private String cvenTelefono;

    private List<Cupones> vListaCuponesVenta;
    public List<Datoscuponesventa> vListaDatosCuponesImpresion;

    //busqueda de cupon / comprobacion de cupon
    private Datoscuponesventa cuponBuscado;
    private String codCuponB;
    private boolean esCuponValido;

    public boolean isEsCuponValido() {
        return esCuponValido;
    }

    public void setEsCuponValido(boolean esCuponValido) {
        this.esCuponValido = esCuponValido;
    }

    public String getCodCuponB() {
        return codCuponB;
    }

    public void setCodCuponB(String codCuponB) {
        this.codCuponB = codCuponB;
    }

    public Datoscuponesventa getCuponBuscado() {
        return cuponBuscado;
    }

    public void setCuponBuscado(Datoscuponesventa cuponBuscado) {
        this.cuponBuscado = cuponBuscado;
    }
    
    public List<Datoscuponesventa> getvListaDatosCuponesImpresion() {
        vListaDatosCuponesImpresion = cuponesImpresion();
        return vListaDatosCuponesImpresion;
    }

    public void setvListaDatosCuponesImpresion(List<Datoscuponesventa> vListaDatosCuponesImpresion) {
        this.vListaDatosCuponesImpresion = vListaDatosCuponesImpresion;
    }
    
    public List<Cupones> getvListaCuponesVenta() {
        return vListaCuponesVenta;
    }

    public void setvListaCuponesVenta(List<Cupones> vListaCuponesVenta) {
        this.vListaCuponesVenta = vListaCuponesVenta;
    }
    
    public Integer getCvenCantidad() {
        return cvenCantidad;
    }

    public void setCvenCantidad(Integer cvenCantidad) {
        this.cvenCantidad = cvenCantidad;
    }

    public String getCvenNombre() {
        return cvenNombre;
    }

    public void setCvenNombre(String cvenNombre) {
        this.cvenNombre = cvenNombre;
    }

    public String getCvenEmail() {
        return cvenEmail;
    }

    public void setCvenEmail(String cvenEmail) {
        this.cvenEmail = cvenEmail;
    }

    public String getCvenTelefono() {
        return cvenTelefono;
    }

    public void setCvenTelefono(String cvenTelefono) {
        this.cvenTelefono = cvenTelefono;
    }
    
    
    private List<Formaspago> fpago;  

    public List<Formaspago> getFpago() {
        
        Query query = em.createNamedQuery("Formaspago.findAll");
        
        fpago = query.getResultList();
        
        return fpago;
    }

    public void setFpago(List<Formaspago> fpago) {
        this.fpago = fpago;
    }
    
    public Negocios getnC() {
        return nC;
    }

    public void setnC(Negocios nC) {
        this.nC = nC;
    }

    public Ofertas getoC() {
        return oC;
    }

    public void setoC(Ofertas oC) {
        this.oC = oC;
    }

    public void seteaOfertaCompra(Integer ofCompra){
        
        Query query = em.createNamedQuery("Ofertas.findByIdOferta");
        query.setParameter("idOferta", ofCompra);
        oC = (Ofertas)query.getSingleResult();
        
        query = em.createNamedQuery("Negocios.findByIdNegocio");
        query.setParameter("idNegocio", oC.getOfeNegocio());
        nC = (Negocios)query.getSingleResult();
        
        Map sMap;
        sMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
        controlPrincipal cp = (controlPrincipal) sMap.get("cPri");
        cp.pagCentro = "ofertas/comprarcupon";
        
    }
    
        public void isCantidadValid(FacesContext ctx, UIComponent component, Object  value) throws ValidatorException
	{
                Integer cupCant = Integer.valueOf(value.toString());
		                
                Query query = em.createNativeQuery("select count(*) from bdagrupados.ventas where ven_oferta = " + oC.getIdOferta());
                Long numOf = (Long)query.getSingleResult();
                
                FacesContext context = FacesContext.getCurrentInstance();
                                
                if(cupCant > (oC.getOfeMaxpordia() - numOf)){
                    FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    context.getApplication().evaluateExpressionGet(context, "Maximo de cupones excedido. Maximo " + (oC.getOfeMaxpordia() - numOf), String.class)
                        ,null);
                    //context.addMessage(null, message);
			//throw new ValidatorException( context.getMessageList().get(context.getMessageList().size()-1));
                    throw new ValidatorException(message);
                }
                
	}
        
        public void efectuarCompra() throws MalformedURLException, EmailException {
                FacesContext context = FacesContext.getCurrentInstance();
            
                Ventas vC = new Ventas(); //datos de venta
                vC.setVenUserNombre(cvenNombre);
                vC.setVenCantidad(cvenCantidad);
                vC.setVenUserTelefono(cvenTelefono);
                
                vC.setVenFecha(new Date());
                
                Map sMap;
                sMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
                controlPrincipal cp = (controlPrincipal) sMap.get("cPri");
                Usuarios cu = (Usuarios) sMap.get("user");
                if(cp.esUsuario){
                    vC.setVenUserEmail(cu.getUsuEmail());    
                }else{
                    vC.setVenUserEmail(cvenEmail);
                }
                
                vC.setVenOferta(oC.getIdOferta());
                
                if(oC.getOfePeriodovalidez().equals(0)){
                    vC.setVenCaducidad(oC.getOfeFecfin());
                }else{
                    Calendar c = Calendar.getInstance();
                    c.setTime(new Date()); 
                    c.add(Calendar.DATE, oC.getOfePeriodovalidez()); // Adding 5 days
                    vC.setVenCaducidad(c.getTime());
                }

                try {
                    utx2.begin();
                    em.persist(vC);
                    utx2.commit();
                    
                    Cupones cupon = new Cupones();
                    Query query = em.createNativeQuery("select * from bdagrupados.ventas where ven_user_email = '" + vC.getVenUserEmail() + "' order by id_venta desc limit 1",Ventas.class);
                    Ventas rV = (Ventas)query.getSingleResult();
                    for(int i=1;i<=vC.getVenCantidad();i++){
                        String codC = oC.getIdOferta() + "0" + rV.getIdVenta() + "0" + i + "0" + (int) (Math.random()* 19999999+1);
                        //codC = String.format("%027d", Long.parseLong(codC));
                        //codC = "1" + codC;
                        cupon.setCupVenta(rV.getIdVenta());
                        cupon.setCupCodigo(codC);
                        cupon.setCupEstado("ACTIVO");
                        utx2.begin();
                        em.persist(cupon);
                        utx2.commit();
                    }
                    
                    FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
                        context.getApplication().evaluateExpressionGet(context, "Compra realizada!", String.class)
                            ,context.getApplication().evaluateExpressionGet(context, "Recibiras un email con mas info.", String.class));
                    context.addMessage("creategrowl", message);


                    //Carga la lista de solicitudes
                    vListaCuponesVenta = cuponesVenta(rV.getIdVenta());
                    
                    enviarEmailCompra(vC.getVenUserEmail(), cvenNombre);
                    
                    //pone la variable de sesion "PAGINA"
                    controlPrincipal bm = (controlPrincipal) sMap.get("cPri");
                    bm.pagCentro = "ofertas/cuponesventa";

                    //return "app-main";
                    //return null;
                } catch (NotSupportedException | SystemException | RollbackException | HeuristicMixedException | HeuristicRollbackException | SecurityException | IllegalStateException | ELException e) {               
                    FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
                                                            "Error creating request!",
                                                            "Unexpected error when creating your request.  Please contact the system Administrator");
                    context.addMessage(null, message);
                    Logger.getAnonymousLogger().log(Level.SEVERE,
                                                    "Unable to create new request",
                                                    e);
                    //return null;
                }     
        }
        
        public List<Cupones> cuponesVenta(Integer idV){
            
            Query query = em.createNamedQuery("Cupones.findByCupVenta");
            query.setParameter("cupVenta", idV);
            
            return query.getResultList();
        }
        
        public void busquedaCupon(){
                
            Query query = em.createNamedQuery("Datoscuponesventa.findByCupCodigo");
            query.setParameter("cupCodigo", codCuponB);
            
            if(query.getResultList().isEmpty()){
                esCuponValido = false;
            }else{
                cuponBuscado = (Datoscuponesventa)query.getResultList().get(0);
                esCuponValido = true;
            }    
        
        }
        
        
        public List<Datoscuponesventa> cuponesImpresion()
	{
                Integer vId = vListaCuponesVenta.get(0).getCupVenta();
                
                Query query = em.createNamedQuery("Datoscuponesventa.findByIdVenta");
                query.setParameter("idVenta", vId);
                return query.getResultList();

                
	}
        
         //public DefaultStreamedContent getCodigoEAN(String cEAN,Integer vAlto, Integer vAncho) throws IOException, BarcodeException {
        public String getCodigoEAN(String cEAN,Integer vAlto, Integer vAncho) throws IOException, BarcodeException {

             if(cEAN.isEmpty()){
                System.out.println("EAN retorna 1");
                cEAN = "1";
            } 
             
            JBarcodeBean barcode = new JBarcodeBean();

            // nuestro tipo de codigo de barra
            barcode.setCodeType(new Interleaved25());
            //barcode.setCodeType(new Code39());

            // nuestro valor a codificar y algunas configuraciones mas
             System.out.println("EAN enviado: " + cEAN);
            barcode.setCode(cEAN);
            //String.format("%010d", Integer.parseInt(cEAN));
            //barcode.setCode("1234554321987654321123456789");
            barcode.setCheckDigit(true);

            BufferedImage bufferedImage = barcode.draw(new BufferedImage(vAncho, vAlto, BufferedImage.TYPE_INT_RGB));

            // guardar en disco como png
            //File file = new File("/resources/img/codigos/" + cEAN + ".png");
            String relativeWebPath = "/img/codigos/" + cEAN + ".png";
            ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
            String absoluteDiskPath = servletContext.getRealPath(relativeWebPath);
            File file = new File(absoluteDiskPath);
            ImageIO.write(bufferedImage, "png", file);
            /*
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "png", baos);
            InputStream is = new ByteArrayInputStream(baos.toByteArray());
            return new DefaultStreamedContent(is); */
            return cEAN + ".png";

        }

        public void AsignaNegocioSeleccionado(){
            
            Map sMap;
            sMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
            controlNegocios cn = (controlNegocios) sMap.get("cNeg");
            cn.SelectedNeg = this.nC;
            System.out.println("Asigna el neg selected:");
            System.out.println("negocio orignal: " + nC.getNegNombre());
            System.out.println("negocio selected: " + cn.getCnegNombre());
            
        }
        
        public void enviarEmailCompra(String emailTo, String emailNombre) throws MalformedURLException, EmailException{

                // Create the email message
              HtmlEmail email = new HtmlEmail();
              email.setHostName("smtp.gmail.com");
              email.addTo(emailTo, emailNombre);
              email.setSmtpPort(465);
              email.setAuthenticator(new DefaultAuthenticator("viscatorrero@gmail.com", "vqwuqniowfnujeat"));
              email.setSSLOnConnect(true);
              email.setFrom("viscatorrero@gmail.com","AgrupadosSA");
              email.setSubject("Tus cupones comprados!");

 
              vListaDatosCuponesImpresion = cuponesImpresion();
              String mensajeHTML ="";
              for(int i=0;i<vListaDatosCuponesImpresion.size();i++){

                  // embed the image and get the content id
                  URL url = new URL("http://localhost:8080/AgrupadosSA/img/cuponFondo.png");
                  String cidFondo = email.embed(url, "Fondo cupon");
                  //url = new URL("http://localhost:8080/AgrupadosSA/img/codigos/" + vListaDatosCuponesImpresion.get(i).getCupCodigo() + ".png");
                  //String cidEAN =  email.embed(url, "Codigo cupon");

                  System.out.println("Tamaño de lista: " + vListaDatosCuponesImpresion.size());
                  System.out.println("Codigo evluandose: " + vListaDatosCuponesImpresion.get(i).getCupCodigo());

                  mensajeHTML = mensajeHTML + "<br>" + "<table class='tablaD' border='0' cellspacing='1' cellpadding='0' background='cid:" + cidFondo + "'>\n" +
                      "                <tr>\n" +
                      "                    <td width='332' ><p class='titulo'>" + vListaDatosCuponesImpresion.get(i).getOfeTitulo() + "<br />\n" +
                      "                            <span class='descripcion'>" + vListaDatosCuponesImpresion.get(i).getOfeDescripcion() + "</span></p></td>\n" +
                      "                        <td>" + vListaDatosCuponesImpresion.get(i).getNegNombre() + "</td>\n" +
                      "                </tr>\n" +
                      "                <tr>\n" +
                      "                    <td width='332' align='center' valign='middle'><p class='descCentro'>Con este cupón ahorras un <strong>" + vListaDatosCuponesImpresion.get(i).getOfeAhorro() + "</strong>%.</p>\n" +
                      "                  <p class='descCentro'>No acumulable a otras ofertas en el restaurante.</p></td>\n" +
                      "                    <td align='center' valign='top' class='validez'><p>Valido para disfrutarse hasta la fecha: " + vListaDatosCuponesImpresion.get(i).getVenCaducidad() + "</p>\n" +
                      "                      <p>Valido para horario de: " + vListaDatosCuponesImpresion.get(i).getOfeTipo() + "</p></td>\n" +
                      "                </tr>\n" +
                      "                <tr>\n" +
                      "                    <td width='332' align='center' valign='middle' class='nombreRest'><p>      Restaurante " + vListaDatosCuponesImpresion.get(i).getNegNombre() + "<br />\n" +
                      "                            <span class='datosRest'>" + vListaDatosCuponesImpresion.get(i).getNegDireccion() + "<br />\n" +
                      "                                Email: " + vListaDatosCuponesImpresion.get(i).getNegEmail() + " Web: " + vListaDatosCuponesImpresion.get(i).getNegPaginaweb() + "<br />\n" +
                      "                                Telefono: " + vListaDatosCuponesImpresion.get(i).getNegTelefono() + "</span></p></td>\n" +
                      "                    <td align='center' valign='top'>\n" +
                      //"                        <img src='cid:" + cidEAN + "'>\n" +
                          vListaDatosCuponesImpresion.get(i).getCupCodigo() + "\n" +
                      "                        </td>\n" +
                      "                </tr>\n" +
                      "              </table>";

                  }
              String mensajeTotal = "<html xmlns='http://www.w3.org/1999/xhtml'\n" +
                      "      xmlns:p='http://primefaces.org/ui'\n" +
                      "      xmlns:h='http://xmlns.jcp.org/jsf/html'\n" +
                      "      xmlns:f='http://xmlns.jcp.org/jsf/core'>\n" +
                      "<h:body>\n" +
                      "\n" +
                      "<style type='text/css'>\n" +
                      ".validez {\n" +
                      "	font-family: Arial, Helvetica, sans-serif;\n" +
                      "	font-size:xx-small;\n" +
                      "}\n" +
                      ".titulo {\n" +
                      "	font-family: Arial Black, Gadget, sans-serif;\n" +
                      "	font-size:x-large;\n" +
                      "	text-align:center;\n" +
                      "	color:red;\n" +
                      "}\n" +
                      ".descripcion {\n" +
                      "	font-family: Arial, Helvetica, sans-serif;\n" +
                      "	font-size: medium;\n" +
                      "	text-align:center;\n" +
                      "}\n" +
                      ".descCentro {\n" +
                      "	font-family: Tahoma, Geneva, sans-serif;\n" +
                      "		font-size:x-small;\n" +
                      "		text-align:center;\n" +
                      "}\n" +
                      ".nombreRest {\n" +
                      "	font-family: Arial Black, Gadget, sans-serif;\n" +
                      "	font-size:x-small;\n" +
                      "}\n" +
                      ".datosRest {\n" +
                      "	font-family: Arial, Helvetica, sans-serif;\n" +
                      "	font-size:xx-small;\n" +
                      "}\n" +
                      ".codigoEAN {\n" +
                      "	font-family: Courier New, Courier, monospace;\n" +
                      "	font-size:small;\n" +
                      "}\n" +
                      ".tablaD {\n" +
                      "	height: 266px;\n" +
                      "	width: 497px;\n" +
                      "        -webkit-print-color-adjust:exact;\n" +
                      "}\n" +
                      ".ui-datagrid-content {\n" +
                      "   border: none;\n" +
                      "}  \n" +
                      "</style>\n" +
                      "\n" +
                      "\n" +
                      "    ";

              mensajeTotal = mensajeTotal + mensajeHTML + "</h:body>\n" +
                                                          "</html>";

              // set the html message
              email.setHtmlMsg(mensajeTotal);

              // set the alternative message
              email.setTextMsg("Your email client does not support HTML messages");

              // send the email
              email.send();

          }
        
    }
